/* SPDX-License-Identifier: GPL-2.0 */

#pragma once

#include <linux/err.h>
#include <linux/sched.h>

struct task_struct *kthread_create_on_node(int (*threadfn)(void *data),
                                           void *data, int node,
                                           const char namefmt[], ...);

#define kthread_create(threadfn, data, namefmt, arg...) \
    kthread_create_on_node(threadfn, data, 0, namefmt, ##arg)

/**
 * kthread_run - create and wake a thread.
 * @threadfn: the function to run until signal_pending(current).
 * @data: data ptr for @threadfn.
 * @namefmt: printf-style name for the thread.
 *
 * Description: Convenient wrapper for kthread_create() followed by
 * wake_up_process().  Returns the kthread or ERR_PTR(-ENOMEM).
 */
#define kthread_run(threadfn, data, namefmt, ...)                                         \
    ({                                                                                    \
        struct task_struct *__k = kthread_create(threadfn, data, namefmt, ##__VA_ARGS__); \
        if (!IS_ERR(__k))                                                                 \
            wake_up_process(__k);                                                         \
        __k;                                                                              \
    })

void kthread_exit(long result);

struct task_struct *kthread_create_on_cpu(int (*threadfn)(void *data),
                                          void *data, unsigned int cpu,
                                          const char *namefmt);
int kthread_park(struct task_struct *k);
void kthread_unpark(struct task_struct *k);
void kthread_set_per_cpu(struct task_struct *k, int cpu);

void kthread_parkme(void);
bool kthread_should_park(void);
bool kthread_should_stop(void);
int kthread_stop_put(struct task_struct *k);
